﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;

namespace CloudStorageLight.Core.WebDav
{
    public class CloudBlobManager : IDisposable
    {
        private BlobServiceBase Service { get; set; }

        /// <summary>
        /// Creates Azure Storage Account with a given container name
        /// </summary>
        /// <param name="connectionString">Azure Blob Connection String</param>
        /// <param name="containerName">Azure Container Name</param>
        /// <param name="IsSecureContainer">True=private,False=public</param>
        public CloudBlobManager(BlobServiceBase service)
        {
            this.Service = service;

        }

        protected virtual BlobUser GetCurrentUser()
        {
            return new BlobUser(System.Web.HttpContext.Current.User);
        }

        protected virtual string GetPath(string blobName)
        {
            if (blobName.StartsWith("/")) return blobName;
            return "/" + blobName;
        }

        #region Public Functions
        /// <summary>
        /// Downloads a blob
        /// </summary>
        /// <param name="containerName">Blob Cntainer Name</param>
        /// <param name="blobName">Blob Name</param>
        /// <returns>The contents of a blob as a MemoryStream</returns>
        public async Task DownloadBlobAsync(String blobName, Stream outstream)
        {
            await Service.DownloadFileAsync(GetCurrentUser(), GetPath(blobName), outstream);
        }

        /// <summary>
        /// Deletes a blob
        /// </summary>
        /// <param name="containerName">Blob Cntainer Name</param>
        /// <param name="blobName">Blob Name</param>
        public async Task<bool> DeleteBlobAsync(String blobName)
        {
            await Service.DeleteFileAsync(GetCurrentUser(), GetPath(blobName));
            return true;
        }

        /// <summary>
        /// Uploads a file as blob
        /// </summary>
        /// <param name="containerName">Blob Cntainer Name</param>
        /// <param name="blobStream">Blob MemoryStream content</param>
        /// <param name="blobName">Blob Name</param>
        public async Task UploadBlobAsync(MemoryStream blobStream, String blobName)
        {
            string mime = System.Web.MimeMapping.GetMimeMapping(blobName);
            await Service.UploadFileAsync(GetCurrentUser(), GetPath(blobName), blobStream, mime);
        }

        /// <summary>
        /// Retrieves Blobs Attributes
        /// </summary>
        /// <param name="fileName">Filename</param>
        /// <returns></returns>
        public async Task<BlobItem> DownloadBlobAttributes(string fileName)
        {

            var path = GetPath(fileName);

            if (!await Service.ExistsAsync(path)) return null;
            var result = await Service.GetBlobItemAsync(GetCurrentUser(), path);
            return result;
        }

        /// <summary>
        /// Checks is a file name exists in Azure Container
        /// </summary>
        /// <param name="fileName">Name of the file to be checked</param>
        /// <returns>True if file exists, False if not</returns>
        public async Task<bool> FileExistAsync(string fileName)
        {
            var path = GetPath(fileName);
            return await Service.ExistsAsync(path);
        }

        public async Task CheckOutAsync(string fileName, int timeout, string lockOwner, string opaqueLock = null)
        {
            var path = GetPath(fileName);
            await Service.CheckOutAsync(GetCurrentUser(), path, lockOwner, timeout, opaqueLock);
            var file = await Service.GetFileAsync(GetCurrentUser(), path);
        }
        
        #endregion

        void IDisposable.Dispose()
        {
            if (Service != null) Service.Dispose();
        }
    }
}

//using Microsoft.WindowsAzure.Storage;
//using Microsoft.WindowsAzure.Storage.Blob;
//using System;
//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Text;
//using System.Text.RegularExpressions;
//using System.Threading.Tasks;
//using System.Web;

//namespace CloudStorageLight.Core.WebDav
//{
//    public class CloudBlobManager : IDisposable
//    {
//        private BlobServiceBase Service { get; set; }

//        /// <summary>
//        /// Creates Azure Storage Account with a given container name
//        /// </summary>
//        /// <param name="connectionString">Azure Blob Connection String</param>
//        /// <param name="containerName">Azure Container Name</param>
//        /// <param name="IsSecureContainer">True=private,False=public</param>
//        public CloudBlobManager(BlobServiceBase service)
//        {
//            this.Service = service;

//        }

//        protected virtual BlobUser GetCurrentUser()
//        {
//            return new BlobUser(System.Web.HttpContext.Current.User);
//        }

//        protected virtual string GetPath(string blobName)
//        {
//            return "/" + blobName;
//        }

//        #region Public Functions
//        /// <summary>
//        /// Downloads a blob
//        /// </summary>
//        /// <param name="containerName">Blob Cntainer Name</param>
//        /// <param name="blobName">Blob Name</param>
//        /// <returns>The contents of a blob as a MemoryStream</returns>
//        public Task<MemoryStream> DownloadBlobAsync(String blobName)
//        {

//            var teamStream = new MemoryStream();

//            using (MemoryStream memoryStream = new MemoryStream())
//            {
//                return Service.DownloadFileAsync(GetCurrentUser(), GetPath(blobName), teamStream)
//                    .ContinueWith((x) =>
//                    {
//                        return teamStream;
//                    });
//            }
//        }

//        /// <summary>
//        /// Deletes a blob
//        /// </summary>
//        /// <param name="containerName">Blob Cntainer Name</param>
//        /// <param name="blobName">Blob Name</param>
//        public Task<bool> DeleteBlobAsync(String blobName)
//        {
//            return Service.DeleteFileAsync(GetCurrentUser(), GetPath(blobName))
//                .ContinueWith((x) =>
//                {
//                    return true;
//                });
//        }

//        /// <summary>
//        /// Uploads a file as blob
//        /// </summary>
//        /// <param name="containerName">Blob Cntainer Name</param>
//        /// <param name="blobStream">Blob MemoryStream content</param>
//        /// <param name="blobName">Blob Name</param>
//        public Task UploadBlobAsync(MemoryStream blobStream, String blobName)
//        {
//            string mime = System.Web.MimeMapping.GetMimeMapping(blobName);
//            return Service.UploadFileAsync(GetCurrentUser(), GetPath(blobName), blobStream, mime).ContinueWith((x)=>{
//                return;
//            });
//        }

//        /// <summary>
//        /// Retrieves Blobs Attributes
//        /// </summary>
//        /// <param name="fileName">Filename</param>
//        /// <returns></returns>
//        public Task<BlobItem> DownloadBlobAttributes(string fileName)
//        {
//            return DownloadBlobAttributesSubAsync(fileName).ContinueWith(x =>
//            {
//                return x.Result;
//            });

//        }

//        private async Task<BlobItem> DownloadBlobAttributesSubAsync(string fileName)
//        {

//            var path = GetPath(fileName);

//            if (!await Service.ExistsAsync(path)) return null;
//            return await Service.GetBlobItemAsync(GetCurrentUser(), path);

//        }

//        /// <summary>
//        /// Checks is a file name exists in Azure Container
//        /// </summary>
//        /// <param name="fileName">Name of the file to be checked</param>
//        /// <returns>True if file exists, False if not</returns>
//        public Task<bool> FileExist(string fileName)
//        {
//            var path = GetPath(fileName);
//            return Service.ExistsAsync(path).ContinueWith((x)=>{
//                return x.Result;
//            });
//        }
//        #endregion

//        void IDisposable.Dispose()
//        {
//            if (Service != null) Service.Dispose();
//        }
//    }
//}

